package com.writing.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.writing.controller.VideoGenerationController.VideoGenerationRequest;
import com.writing.controller.VideoGenerationController.VideoTaskResponse;
import com.writing.entity.ApiConfig;
import com.writing.service.ApiConfigService;
import com.writing.service.VideoGenerationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 视频生成服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class VideoGenerationServiceImpl implements VideoGenerationService {

    private final ApiConfigService apiConfigService;
    private final RestTemplate restTemplate = new RestTemplate();

    @Override
    public VideoTaskResponse generateVideo(VideoGenerationRequest request, Long userId) {
        try {
            // 获取启用的API配置
            List<ApiConfig> configs = apiConfigService.getEnabledConfigs();
            if (configs.isEmpty()) {
                throw new RuntimeException("未找到可用的API配置");
            }

            ApiConfig config = configs.get(0);
            String baseUrl = config.getBaseUrl();
            String apiKey = config.getApiKey();
            
            // 规范化baseUrl
            baseUrl = baseUrl.trim();
            while (baseUrl.endsWith("/")) {
                baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
            }
            
            // 构建API URL
            String endpoint = "/v1/videos";
            String apiUrl;
            if (baseUrl.endsWith("/v1")) {
                apiUrl = baseUrl + endpoint.substring(3);
            } else {
                apiUrl = baseUrl + endpoint;
            }

            // 构建multipart/form-data请求
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
            headers.set("Authorization", "Bearer " + apiKey);

            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
            body.add("prompt", request.getPrompt());
            body.add("model", request.getModel() != null ? request.getModel() : "sora-2");
            
            if (request.getSeconds() != null && !request.getSeconds().isEmpty()) {
                body.add("seconds", request.getSeconds());
            }
            
            if (request.getSize() != null && !request.getSize().isEmpty()) {
                body.add("size", request.getSize());
            }
            
            // 处理参考图片
            if (request.getInputReference() != null && !request.getInputReference().isEmpty()) {
                try {
                    ByteArrayResource resource = new ByteArrayResource(request.getInputReference().getBytes()) {
                        @Override
                        public String getFilename() {
                            return request.getInputReference().getOriginalFilename();
                        }
                    };
                    body.add("input_reference", resource);
                } catch (Exception e) {
                    log.warn("处理参考图片失败: {}", e.getMessage());
                }
            }

            HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(body, headers);

            log.info("调用视频生成API: {}", apiUrl);
            log.info("请求参数: prompt={}, model={}, seconds={}, size={}", 
                    request.getPrompt(), request.getModel(), request.getSeconds(), request.getSize());

            // 发送请求
            VideoTaskResponse response;
            try {
                ResponseEntity<String> httpResponse = restTemplate.exchange(
                        apiUrl,
                        HttpMethod.POST,
                        entity,
                        String.class
                );

                if (httpResponse.getStatusCode() != HttpStatus.OK) {
                    throw new RuntimeException("API调用失败，状态码: " + httpResponse.getStatusCode());
                }

                String responseBody = httpResponse.getBody();
                log.info("API响应: {}", responseBody);
                
                response = parseVideoTaskResponse(responseBody);
                
            } catch (HttpClientErrorException e) {
                String errorBody = e.getResponseBodyAsString();
                log.error("API调用失败 (4xx): {}", errorBody);
                throw new RuntimeException("API调用失败: " + errorBody);
            } catch (HttpServerErrorException e) {
                String errorBody = e.getResponseBodyAsString();
                log.error("API调用失败 (5xx): {}", errorBody);
                throw new RuntimeException("API服务器错误: " + errorBody);
            } catch (RestClientException e) {
                log.error("API调用失败: {}", e.getMessage(), e);
                throw new RuntimeException("API调用失败: " + e.getMessage());
            }

            return response;

        } catch (Exception e) {
            log.error("视频生成失败", e);
            throw new RuntimeException("视频生成失败: " + e.getMessage(), e);
        }
    }

    @Override
    public VideoTaskResponse getVideoTask(String videoId, Long userId) {
        try {
            List<ApiConfig> configs = apiConfigService.getEnabledConfigs();
            if (configs.isEmpty()) {
                throw new RuntimeException("未找到可用的API配置");
            }

            ApiConfig config = configs.get(0);
            String baseUrl = config.getBaseUrl();
            String apiKey = config.getApiKey();
            
            baseUrl = baseUrl.trim();
            while (baseUrl.endsWith("/")) {
                baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
            }
            
            String endpoint = "/v1/videos/" + videoId;
            String apiUrl;
            if (baseUrl.endsWith("/v1")) {
                apiUrl = baseUrl + endpoint.substring(3);
            } else {
                apiUrl = baseUrl + endpoint;
            }

            HttpHeaders headers = new HttpHeaders();
            headers.set("Authorization", "Bearer " + apiKey);

            HttpEntity<String> entity = new HttpEntity<>(headers);

            log.info("查询视频任务: {}", apiUrl);

            try {
                ResponseEntity<String> httpResponse = restTemplate.exchange(
                        apiUrl,
                        HttpMethod.GET,
                        entity,
                        String.class
                );

                if (httpResponse.getStatusCode() != HttpStatus.OK) {
                    throw new RuntimeException("API调用失败，状态码: " + httpResponse.getStatusCode());
                }

                String responseBody = httpResponse.getBody();
                log.info("API响应: {}", responseBody);
                
                return parseVideoTaskResponse(responseBody);
                
            } catch (HttpClientErrorException e) {
                String errorBody = e.getResponseBodyAsString();
                log.error("API调用失败 (4xx): {}", errorBody);
                throw new RuntimeException("API调用失败: " + errorBody);
            } catch (HttpServerErrorException e) {
                String errorBody = e.getResponseBodyAsString();
                log.error("API调用失败 (5xx): {}", errorBody);
                throw new RuntimeException("API服务器错误: " + errorBody);
            } catch (RestClientException e) {
                log.error("API调用失败: {}", e.getMessage(), e);
                throw new RuntimeException("API调用失败: " + e.getMessage());
            }

        } catch (Exception e) {
            log.error("查询视频任务失败", e);
            throw new RuntimeException("查询视频任务失败: " + e.getMessage(), e);
        }
    }

    @Override
    public Map<String, Object> getVideoContent(String videoId, String variant, Long userId) {
        try {
            List<ApiConfig> configs = apiConfigService.getEnabledConfigs();
            if (configs.isEmpty()) {
                throw new RuntimeException("未找到可用的API配置");
            }

            ApiConfig config = configs.get(0);
            String baseUrl = config.getBaseUrl();
            String apiKey = config.getApiKey();
            
            baseUrl = baseUrl.trim();
            while (baseUrl.endsWith("/")) {
                baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
            }
            
            String endpoint = "/v1/videos/" + videoId + "/content";
            if (variant != null && !variant.isEmpty()) {
                endpoint += "?variant=" + variant;
            }
            
            String apiUrl;
            if (baseUrl.endsWith("/v1")) {
                apiUrl = baseUrl + endpoint.substring(3);
            } else {
                apiUrl = baseUrl + endpoint;
            }

            HttpHeaders headers = new HttpHeaders();
            headers.set("Authorization", "Bearer " + apiKey);

            HttpEntity<String> entity = new HttpEntity<>(headers);

            log.info("获取视频内容: {}", apiUrl);

            try {
                ResponseEntity<byte[]> httpResponse = restTemplate.exchange(
                        apiUrl,
                        HttpMethod.GET,
                        entity,
                        byte[].class
                );

                if (httpResponse.getStatusCode() != HttpStatus.OK) {
                    throw new RuntimeException("API调用失败，状态码: " + httpResponse.getStatusCode());
                }

                byte[] videoData = httpResponse.getBody();
                HttpHeaders responseHeaders = httpResponse.getHeaders();
                
                Map<String, Object> result = new HashMap<>();
                result.put("data", videoData);
                result.put("contentType", responseHeaders.getContentType() != null ? 
                        responseHeaders.getContentType().toString() : "video/mp4");
                result.put("contentLength", responseHeaders.getContentLength());
                
                return result;
                
            } catch (HttpClientErrorException e) {
                String errorBody = e.getResponseBodyAsString();
                log.error("API调用失败 (4xx): {}", errorBody);
                throw new RuntimeException("API调用失败: " + errorBody);
            } catch (HttpServerErrorException e) {
                String errorBody = e.getResponseBodyAsString();
                log.error("API调用失败 (5xx): {}", errorBody);
                throw new RuntimeException("API服务器错误: " + errorBody);
            } catch (RestClientException e) {
                log.error("API调用失败: {}", e.getMessage(), e);
                throw new RuntimeException("API调用失败: " + e.getMessage());
            }

        } catch (Exception e) {
            log.error("获取视频内容失败", e);
            throw new RuntimeException("获取视频内容失败: " + e.getMessage(), e);
        }
    }

    /**
     * 解析视频任务响应
     */
    private VideoTaskResponse parseVideoTaskResponse(String responseBody) {
        JSONObject json = JSON.parseObject(responseBody);
        VideoTaskResponse response = new VideoTaskResponse();
        response.setId(json.getString("id"));
        response.setObject(json.getString("object"));
        response.setModel(json.getString("model"));
        response.setStatus(json.getString("status"));
        
        if (json.containsKey("progress")) {
            response.setProgress(json.getInteger("progress"));
        }
        
        if (json.containsKey("created_at")) {
            response.setCreatedAt(json.getLong("created_at"));
        }
        
        if (json.containsKey("completed_at")) {
            response.setCompletedAt(json.getLong("completed_at"));
        }
        
        if (json.containsKey("expires_at")) {
            response.setExpiresAt(json.getLong("expires_at"));
        }
        
        response.setSize(json.getString("size"));
        response.setSeconds(json.getString("seconds"));
        response.setQuality(json.getString("quality"));
        
        if (json.containsKey("remixed_from_video_id")) {
            response.setRemixedFromVideoId(json.getString("remixed_from_video_id"));
        }
        
        if (json.containsKey("error")) {
            response.setError(json.get("error"));
        }
        
        if (json.containsKey("url")) {
            response.setUrl(json.getString("url"));
        }
        
        return response;
    }
}

